﻿using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Service.Core.EfCoreRepository.Core;
using Service.Framework;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Service.Core.EfCoreRepository.Extension
{
    public static class MediatorExtension
    {
        private const int Max_Deep = 10;

        public static async Task DispatchDomainEventsAsync(this IMediator mediator, DbContext ctx, int deep = 0,
            CancellationToken cancellationToken = default)
        {
            var domainEntities = ctx.ChangeTracker
                .Entries<Entity>()
                .Where(x => x.Entity.GetDomainEvents().Any())
                .ToList();

            var domainEvents = domainEntities
                .SelectMany(x => x.Entity.GetDomainEvents())
                .ToList();
            if (deep > Max_Deep)
            {
                throw new LogicErrorException("领域事件发布超过最大递归深度");
            }

            if (domainEvents.Count == 0)
            {
                return;
            }

            domainEntities.ForEach(entity => entity.Entity.ClearDomainEvents());

            foreach (var domainEvent in domainEvents)
            {
                Guid id = Guid.NewGuid();
                var eventType = domainEvent.GetType();
                var eventTypeName = eventType.FullName ?? eventType.Name;
                try
                {
                    await mediator.Publish(domainEvent, cancellationToken);
                }
                catch (Exception e)
                {
                    throw;
                }
            }

            await DispatchDomainEventsAsync(mediator, ctx, deep + 1, cancellationToken);
        }
      
    }

  
}
